// Copyright (c) 2013-2015 David Muse
// See the COPYING file for more information.

#ifndef WIKITEXT_WIKITEXT_H
#define WIKITEXT_WIKITEXT_H

#include <wikitext/private/wikitextincludes.h>

/** The wikitext class provides a framework for converting WikiText to another
 *  format such as xhtml or plaintext, optionally expanding macros during the
 *  process.
 *
 *  The wikitext class is implemented using the rudiments compiler class.
 *
 *  Formatting and macro expansion modules should be implemented using
 *  children of the rudiments compilermodule class: compilerpreprocessor,
 *  compilerprocessor, and compilerpostprocessor.
 *  */
class WIKITEXT_DLLSPEC wikitext {
	public:
		/** Creates an instance of the wikitext class. */
		wikitext();

		/** Deletes this instance of the wikitext class. */
		virtual	~wikitext();


		/** Instructs the reformat() method to format the output as
		 *  specified by "format" (eg. xhtml, text, etc.) using
		 *  "parameters".
		 *
		 *  "format" should refer to a loadable module named
		 *  wikitextformat_"format"."ext" 
		 *  (where "ext" is .so, .dll, etc.)
		 *
		 *  The module should contain up to three classes named:
		 *  * "format"_preprocessor
		 *  * "format"_processor
		 *  * "format"_postprocessor
		 *
		 *  And up to three functions named:
		 *  * new_"format"_preprocessor()
		 *  * new_"format"_processor()
		 *  * new_"format"_postprocessor()
		 *  which create and return instances of the classes.
		 *  
		 *  The classes should inherit from the corresponding
		 *  children of the rudiments compilermodule class.
		 *
		 *  I.e. "format"_preprocessor should inherit from
		 *  compilerpreprocessor, "format"_processor should inherit
		 *  from compilerprocessor, and "format"_postprocessor should
		 *  inherit from compilerpostprocessor.
		 *
		 *  The reformat() method will pre-process the input using
		 *  "format"_preprocessor, process it using any loaded macro
		 *  handlers, process it using "format"_processor, and then
		 *  post-process it using "format"_postprocessor.
		 *
		 *  See addMacroHandler() and the rudiments compiler class for
		 *  more information.
		 *
		 *  Returns true on success and false on failure. */
		void	setOutputFormat(const char *format,
					const char *parameters);


		/** Adds the specified macro handler "macrohandler".
		 *  
		 *  "macrohandler" should refer to a loadable module named
		 *  wikitextmacrohandler_"macrohandler"."ext" 
		 *  (where "ext" is .so, .dll, etc.)
		 *
		 *  The module should contain a class named "macrohandler"
		 *  which should inherit from the compilerprocessor class,
		 *  and a function named new_"macrohandler"() which creates
		 *  and returns an instance of the class.
		 *
		 *  The reformat() method will pre-process the input using
		 *  "format"_preprocessor, process it using any loaded macro
		 *  handlers, process it using "format"_processor, and then
		 *  post-process it using "format"_postprocessor.
		 *
		 *  See setOutputFormat() and the rudiments compiler class for
		 *  more information.
		 *  
		 *
		 *  A macro can be defined in WikiText as follows:
		 *
		 *  [[name(arguments)]]
		 *
		 *  For example:
		 *
		 * [[Image(http://www.somewhere.org/picture.gif,width=200px,
		 * height=200px,alt='a cool picture')]]
		 *
		 *  In the code tree, it will be represented like:
		 *
		 *  <macro><macro_name>Image</macro_name>
		 *  <macro_args>http://www.somewhere.org/picture.gif,
		 *  width=200px,height=200px,alt='a cool picture'
		 *  </macro_args></macro>
		 *
		 *  A macrohandler should expand some set of macros.
		 *
		 *  For example, a macro handler might expand the above into:
		 *
		 *  <image><image_link>http://www.somewhere.org/picture.gif
		 *  </image_link><image_width>200px</image_width>
		 *  <image_height>200px</image_height>
		 *  <image_alt>a cool picture</image_alt></image>
		 *
		 *  Which an xhtml formatter might then convert to:
		 *
		 *  <img src="http://www.somewhere.org/picture.gif"
		 *  style="width: 200px; height: 200px" alt="a cool picture"/>
		 * */
		void	addMacroHandler(const char *macrohandler);

		/** Removes all macro handlers. */
		void	clearMacroHandlers();


		/** This method pre-processes the input using
		 *  "format"_preprocessor, processes it using any loaded macro
		 *  handlers, processes it using "format"_processor, and then
		 *  post-processes it using "format"_postprocessor.
		 *
		 *  See setOutputFormat(), addMacroHandler() and the rudiments
		 *  compiler class for more information
		 *
		 *  Returns true on success and false on failure. */
		bool	reformat(const char *input, stringbuffer *output);


		/** Returns the error that occurred if reformat() failed. */
		const char	*getError();


		/** Sets the debug level.  Debug is written to standard out. */
		void	setDebugLevel(uint8_t debuglevel);

	#include <wikitext/private/wikitext.h>
};

#endif
